package dk.aiszone.lang.messer.autosource;

import dk.aiszone.lang.autosource.generatorobjects.interfaces.SimpleBlockObject;
import dk.aiszone.lang.messer.autosource.interfaces.AbstractModifiableObject;
import dk.aiszone.lang.messer.autosource.interfaces.ComplexStatement;

/**
 * Representation of an <code>If</code> statement.
 * 
 * @author Ais
 */
public class IfStatement extends AbstractModifiableObject implements ComplexStatement, SimpleBlockObject {

    private final SimpleBlockObject _else;
    private final SimpleBlockObject _then;

    private final String constraint;
    private String modifiedConstraint;

    /**
     * Constructor for the <code>IfStatement</code> object.
     * 
     * @param constraint
     *            The constraint to test.
     * @param _then
     *            The statement to execute if the constraint is <code>true</code>.
     * @param _else
     *            The statement to execute if the constraint is <code>false</code>.
     * @param row
     *            The line of the <code>ModifialbleStatement</code>.
     * @param column
     *            The column of the <code>ModifiableStatement</code>.
     */
    public IfStatement(String constraint, SimpleBlockObject _then, SimpleBlockObject _else, int row, int column) {
        super(row, column);
        this.constraint = constraint;
        this._then = _then;
        this._else = _else;
    }

    @Override
    public Object clone() {
        return new IfStatement(constraint, (SimpleBlockObject)_then.clone(), (SimpleBlockObject)_else.clone(), row, column);
    }

    @Override
    public SimpleBlockObject getChild(int index) {
        if (index == 0) {
            return _then;
        } else if (index == 1) {
            return _else;
        }
        throw new IndexOutOfBoundsException(index + " out of bounds");
    }

    @Override
    public int getChildCount() {
        return (_else != null ? 2 : 1);
    }

    @Override
    public int getNumberOfSupportedModifications() {
        return 2;
    }

    @Override
    public void modify(int index) {
        if (index == 0) {
            modifiedConstraint = "false && (" + constraint + ")";
            log(constraint, modifiedConstraint);
        } else if (index == 1) {
            modifiedConstraint = "true && (" + constraint + ")";
            log(constraint, modifiedConstraint);
        }
        throw new IndexOutOfBoundsException(index + " out of bounds");
    }

    @Override
    public void revert() {
        modifiedConstraint = null;
    }

    @Override
    public String toJava() {
        StringBuilder sb = new StringBuilder();
        sb.append("if(").append((modifiedConstraint != null ? modifiedConstraint : constraint)).append(") {\n");
        if (_then != null) {
            sb.append(_then.toJava()).append("\n");
        }
        sb.append("}");
        if (_else != null) {
            sb.append(" else ");
            if (_else instanceof IfStatement) {
                sb.append(_else.toJava());
            } else {
                sb.append("{\n").append(_else.toJava()).append("\n}\n");
            }
        }
        return sb.toString();
    }
}